import { AfterViewInit, Component, ViewChild } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {
  FormBuilder,
  FormGroup,
  FormsModule,
  ReactiveFormsModule,
} from '@angular/forms';
import { CommonModule, NgOptimizedImage } from '@angular/common';
import { IconComponent } from '../icon/icon.component';
import { SERVER_URL } from '../constant/url.constant';
import { catchError, of, tap } from 'rxjs';
import { MatSnackBar } from '@angular/material/snack-bar';
import { PaginationDto, SearchResultDto } from '../dto/search.dto';
import { TitleCasePipe } from '../pipes/title-case.pipe';
import { DateFnsTzPipe } from '../pipes/date-fns-tz.pipe';
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
import {
  MatPaginator,
  MatPaginatorModule,
  PageEvent,
} from '@angular/material/paginator';
import { MatSortModule, Sort } from '@angular/material/sort';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatMenu, MatMenuItem, MatMenuTrigger } from '@angular/material/menu';

@Component({
  selector: 'app-search',
  imports: [
    FormsModule,
    ReactiveFormsModule,
    CommonModule,
    IconComponent,
    TitleCasePipe,
    DateFnsTzPipe,
    MatTableModule,
    MatPaginatorModule,
    MatProgressBarModule,
    MatSortModule,
    MatIconModule,
    MatButtonModule,
    NgOptimizedImage,
    MatMenu,
    MatMenuItem,
    MatMenuTrigger,
  ],
  templateUrl: './search.component.html',
  standalone: true,
  styleUrl: './search.component.css',
})
export class SearchComponent implements AfterViewInit {
  searchForm: FormGroup;
  // 是否正在加载数据
  loading = false;

  // 源数据
  dataSource = new MatTableDataSource<SearchResultDto>([]);
  // 排序后的数据
  sortedData = new MatTableDataSource<SearchResultDto>(
    this.dataSource.data.slice(),
  );

  // 列名
  columns: string[] = Object.keys(
    Object.assign(new SearchResultDto('', '', '', '', undefined, 0), {
      options: '',
    }),
  ).filter((column) => column !== 'hash');

  // 存储每行的选项框状态
  showOptions: Map<string, boolean> = new Map<string, boolean>();

  @ViewChild(MatPaginator) paginator!: MatPaginator;

  total: number = 0;
  pageSize: number = 0;
  pageIndex: number = 0;

  constructor(
    private http: HttpClient,
    private fb: FormBuilder,
    private snackBar: MatSnackBar,
  ) {
    this.searchForm = this.fb.group({
      query: [''],
    });
  }

  ngAfterViewInit() {
    // 如果使用接口进行分页,则需要将下面的代码注释掉
    // this.dataSource.paginator = this.paginator;
  }

  // 切换选项框的显示/隐藏
  toggleOptions(hash: string): void {
    this.showOptions.set(hash, !this.showOptions.get(hash));
  }

  onSearch(): void {
    const query = this.searchForm.get('query')?.value;
    this.loading = true;

    this.http
      .get<PaginationDto>(SERVER_URL + '/share/records', {
        params: { query },
      })
      .pipe(
        tap((response: PaginationDto) => {
          this.dataSource.data = response.data;
          this.total = response.total;
          this.loading = false;
        }),
        catchError((error) => {
          this.loading = false;
          this.dataSource = new MatTableDataSource<SearchResultDto>([]);
          this.snackBar.open(
            error.message || 'Failed to fetch data. Please try again later.',
            'Close',
            {
              duration: 5000,
              horizontalPosition: 'center',
              verticalPosition: 'top',
            },
          );
          return of([]);
        }),
      )
      .subscribe();
  }

  /**
   * 当触发排序事件时对数据进行排序
   * @param sort
   */
  onSort(sort: Sort) {
    const dataList = this.dataSource.data.slice();

    if (sort.active && sort.direction !== '') {
      this.sortedData = new MatTableDataSource<SearchResultDto>(
        dataList.sort((a, b) => {
          const aValue = (a as any)[sort.active];
          const bValue = (b as any)[sort.active];
          return (
            (aValue < bValue ? -1 : 1) * (sort.direction === 'asc' ? 1 : -1)
          );
        }),
      );
    }

    this.dataSource = this.sortedData;
  }

  /**
   * 判断列是否为日期类型
   * @param column
   */
  isDateColumn(column: string): boolean {
    return column === 'create_time' || column === 'added_time';
  }

  /**
   * 当分页器发生变化时请求数据
   * @param $event
   */
  onPageChanged($event: PageEvent) {
    this.http
      .get<PaginationDto>(SERVER_URL + '/share/records', {
        params: {
          skip: $event.pageIndex * $event.pageSize,
          take: $event.pageSize,
        },
      })
      .subscribe((response: PaginationDto) => {
        this.pageIndex = $event.pageIndex;
        this.pageSize = $event.pageSize;
        this.dataSource.data = response.data;
        this.total = response.total;
      });
  }

  onDelete(hash: string) {
    this.showOptions.delete(hash);
    this.http
      .delete(SERVER_URL + '/share/record', { params: { hash } })
      .pipe(
        tap(() => {
          this.snackBar.open('Record deleted successfully.', 'Close', {
            duration: 5000,
            horizontalPosition: 'center',
            verticalPosition: 'top',
          });
          this.total--;
        }),
        catchError((error) => {
          this.snackBar.open(
            error.message || 'Failed to delete record. Please try again later.',
            'Close',
            {
              duration: 5000,
              horizontalPosition: 'center',
              verticalPosition: 'top',
            },
          );
          return of([]);
        }),
      )
      .subscribe();
    this.dataSource.data = this.dataSource.data.filter(
      (record) => record.hash !== hash,
    );
  }
}
